﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Mrc.Entity;
using Mrc.Application;
using Mrc.Data;
using System.Threading.Tasks;
using System.Threading;
using Chloe.SqlServer;
using Mrc.IISLog.Entity;
namespace Mrc.IISLog
{
    public partial class IISManager
    {
        private static Dictionary<string, List<IISLogEvent>> dictionary = new Dictionary<string, List<IISLogEvent>>();
        private static Dictionary<string, FileInfomation> fileInfoDic = new Dictionary<string, FileInfomation>();
        private static Dictionary<string, string> keywordsDic = new Dictionary<string, string>();
        /// <summary>
        /// 写入记录到内存 多线程异步形式
        /// </summary>
        /// <returns></returns>
        public static  Task<bool> SetLogs()
        {           
            List<FileInfo> files = IOHelper.GetAllFilesInDirectory(GlobalsConfig.ContentRootPath+ "/TestData");
            List<FileInfomation> filesInfo = new List<FileInfomation>();
            foreach (FileInfo info in files)
            {
                var thisFileInfo = new FileInfomation { FileName = info.Name, FileFullName = info.FullName, FileSize = decimal.Round(decimal.Parse(((decimal)info.Length / (1024M * 1024M)).ToString()), 2), CreateTime = info.LastWriteTime };
                filesInfo.Add(thisFileInfo);
                if (!fileInfoDic.ContainsKey(thisFileInfo.FileName))
                {
                    fileInfoDic.Add(thisFileInfo.FileName, thisFileInfo);
                }
            }
            List<string> Paths = new List<string>();
            if(files.Count==0) return  Task.Run(() => true);
            TaskFactory taskfactory = new TaskFactory();
            List<Task> taskList = new List<Task>();
            for (int i = 0; i < filesInfo.Count; i++)
            {
                if (dictionary.ContainsKey(filesInfo[i].FileFullName)) continue;
                taskList.Add(taskfactory.StartNew(new Action<object>(fileinfo =>
                {
                    FileInfomation file = fileinfo as FileInfomation;
                    if (!dictionary.ContainsKey(file.FileName))
                    {
                        using (ParserEngine parser = new ParserEngine(file.FileFullName))
                        {
                            List<IISLogEvent> logs = new List<IISLogEvent>();
                            while (parser.MissingRecords)
                            {
                                logs=parser.ParseLog().ToList();
                                if(!dictionary.ContainsKey(file.FileName))
                                {
                                    dictionary.Add(file.FileName,logs);
                                    var thisfileinfo = fileInfoDic[file.FileName];
                                    thisfileinfo.isRead = true;
                                    fileInfoDic[file.FileName] = thisfileinfo;
                                }
                            }
                            parser.Dispose();
                        }
                    }
                }), filesInfo[i]));
            }
            return Task.Run(() => true);
        }
        /// <summary>
        /// 重现加载
        /// </summary>
        /// <returns></returns>
        public static async Task<bool> ReloadData()
        {
            fileInfoDic.Clear();
            dictionary.Clear();
            fileInfoDic = new Dictionary<string, FileInfomation>();
            dictionary = new Dictionary<string, List<IISLogEvent>>();
            await SetLogs();
            return await Task.FromResult(true);
        }
        /// <summary>
        /// 获取全部的iis日记文件名
        /// </summary>
        /// <returns></returns>
        public static async Task<LayuiTableJson<FileInfomation>> GetAllIISLogsName()
        {
            List<FileInfomation> Logs = new List<FileInfomation>();
            var All = dictionary.Keys;
            foreach (var item in All)
            {
                if (fileInfoDic.ContainsKey(item)) Logs.Add(fileInfoDic[item]);
            }
            return await Task.Run(() => Logs.ToLayuiTable(1, All.Count));
        }

        /// <summary>
        /// 设置关键字
        /// </summary>
        public static void SetKeyWords()
        {
              keywordsDic.Clear();
              var dbContext=DbContextHelper.GetDBContext();
              var keyWordList = dbContext.Query<IISKeyWords>().ToList();              
              keywordsDic = keyWordList.ToDictionary(x => x.keyword, x => x.keyword);
        }
        /// <summary>
        /// 获取关键字
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, string> GetKeyWords()
        {
            if (!keywordsDic.Any())
            {
               SetKeyWords();
            }
            return keywordsDic;
        }

        /// <summary>
        /// 获取某个日记文件的 访问记录
        /// </summary>
        /// <param name="logName"></param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static Task<LayuiTableJson<IISLogEvent>> GetLogs(string logName,int ?page,int pageSize)
        {
            List<IISLogEvent> logList = new List<IISLogEvent>();
            if (dictionary.ContainsKey(logName))
            {
                logList = dictionary[logName];
            }
            return Task.Run(() => logList.ToLayuiTable(page ?? 1, pageSize));         
        }

        /// <summary>
        /// 获取选中的每个日记文件的记录数
        /// </summary>
        /// <param name="iisLogName"></param>
        /// <returns></returns>
        public static Task<BarDataModel> GetIISsVisitCount(string[] iisLogName)
        {
            BarDataModel result = new BarDataModel();
            foreach (var logName in iisLogName)
            {
                if (dictionary.ContainsKey(logName))
                {
                    string time = dictionary[logName].Count > 0 ? dictionary[logName].First().DateTimeEvent.ToString("yyyy-MM-dd"):"";
                    int count = dictionary[logName].Count;
                    result.xdata.Add(time);
                    result.ydata.Add(count);
                }
            }
            return Task.Run(() =>result);
        }

        /// <summary>
        /// 获取iis日记文件的访问量（默认按分钟）
        /// </summary>
        /// <param name="logName"></param>
        /// <returns></returns>
        public static Task<BarDataModel> GetIISVisitCountMinutes(string logName,string timeFormatStr= "MM-dd HH:mm")
        {
            BarDataModel result = new BarDataModel();
            if (dictionary.ContainsKey(logName))
            {
                string time = dictionary[logName].Count > 0 ? dictionary[logName].First().DateTimeEvent.ToString("MM-dd") : "";
                var List = dictionary[logName];
               var resultdata= List.Select(n => new {Time = n.DateTimeEvent.ToString(timeFormatStr)})
                .GroupBy(n => n.Time).Select(n => new {time=n.Key,times = n.Count() }).ToList();
                foreach (var item in resultdata)
                {
                    result.xdata.Add(item.time);
                    result.ydata.Add(item.times);
                }
            }
            return Task.Run(() => result);
        }
        /// <summary>
        /// 获取日记文件的每个ip的总访问量,访问Url
        /// </summary>
        /// <param name="logName"></param>
        /// <returns></returns>
        public static Task<LayuiTableJson<IPsInfoModel>> GetLogIps(string logName)
        {
            List<IPsInfoModel> ipList = new List<IPsInfoModel>();
            if (!dictionary.ContainsKey(logName))
            {
                return Task.Run(() => ipList.ToLayuiTable(1,100));
            }
            var IISLogs = dictionary[logName];
            ipList=IISLogs.Select(x => new { ip=x.cIp,path=x.csUriStem,iswarning=x.isWarning}).GroupBy(x=>x.ip).Select(x=>new IPsInfoModel { ip=x.Key,count=x.Count(),Paths=x.Select(m=>m.path).ToList(),isWarning=x.Any(w=>w.iswarning)}).OrderByDescending(x=>x.count).ToList();
            return Task.Run(() => ipList.ToLayuiTable(1, ipList.Count()));
        }

        /// <summary>
        /// 日记插入数据库
        /// </summary>
        /// <param name="logName"></param>
        /// <returns></returns>
        public static Task<bool> InsetList(string logName)
        {
            return Task.Run(() => {
                string connString = GlobalsConfig.Configuration["db:ConnString"];
                MsSqlContext dbContext = new MsSqlContext(connString);
                List<IISLogEvent> logList = new List<IISLogEvent>();
                if (dictionary.ContainsKey(logName))
                {
                    logList = dictionary[logName];
                }
                dbContext.BulkInsert(logList);
                dbContext.Dispose();
                return true;
            });
        }
    }
}
